package biz

import (
	"beetle/internal/model"
	"beetle/internal/pkg/constant"
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
)

type RedisSettingService interface {
	Save(model *model.RedisSetting) error
	Update(model *model.RedisSetting) error
	Remove(id int) error
	Find(id int) (*model.RedisSetting, error)
	List(model *model.RedisSetting) []model.RedisSetting
	Option() []map[string]interface{}
	CheckConn(id int) error
}

type RedisSettingRepo interface {
	Save(model *model.RedisSetting) bool
	Update(model *model.RedisSetting) bool
	Remove(id int) bool
	Find(id int) *model.RedisSetting
	List(model *model.RedisSetting) []model.RedisSetting
	Option() []map[string]interface{}
	CheckConn(id int) error
}

type redisSettingService struct {
	repo RedisSettingRepo
}

func (srv *redisSettingService) Save(setting *model.RedisSetting) error {

	if setting.Name == "" {
		return errors.New("参数名不能为空")
	}

	if setting.Host == "" {
		setting.Host = "localhost"
	}

	if setting.Port == 0 {
		setting.Port = 6379
	}

	success := srv.repo.Save(setting)
	if success {
		return nil
	}
	return errors.New("保存失败")
}

func (srv *redisSettingService) Update(setting *model.RedisSetting) error {
	if setting.ID == 0 {
		return errors.New("ID不能为空")
	}

	success := srv.repo.Update(setting)
	if success {
		return nil
	}
	return errors.New("更新失败")
}

func (srv *redisSettingService) Remove(id int) error {
	success := srv.repo.Remove(id)
	if success {
		return nil
	}
	// TODO 记录日志
	return errors.New("删除失败")
}

func (srv *redisSettingService) Find(id int) (*model.RedisSetting, error) {
	if id == 0 {
		return nil, errors.New("ID不能为空")
	}
	setting := srv.repo.Find(id)
	if setting == nil {
		return nil, errors.New("未找到有效的配置信息")
	}
	return setting, nil
}

func (srv *redisSettingService) List(setting *model.RedisSetting) []model.RedisSetting {
	return srv.repo.List(setting)
}

func (srv *redisSettingService) Option() []map[string]interface{} {
	return srv.repo.Option()
}

func (srv *redisSettingService) CheckConn(id int) error {
	return srv.repo.CheckConn(id)
}

func NewRedisSettingService(repo RedisSettingRepo) *redisSettingService {
	return &redisSettingService{repo}
}

type redisSettingRepo struct {
	db *gorm.DB
}

func (repo *redisSettingRepo) Save(setting *model.RedisSetting) bool {
	result := repo.db.Create(setting)
	if result.Error != nil {
		return false
	}
	return true
}

func (repo *redisSettingRepo) Update(setting *model.RedisSetting) bool {
	result := repo.db.Where(" DEL_FLAG = ? AND ID = ? ", constant.UNDELETE, setting.ID).Updates(setting)
	if result.Error != nil {
		return false
	}
	return true
}

func (repo *redisSettingRepo) Remove(id int) bool {
	result := repo.db.Model(&model.RedisSetting{ID: id}).Update("DEL_FLAG", constant.DELETE)
	if result.Error != nil {
		return false
	}
	return true
}

func (repo *redisSettingRepo) Find(id int) *model.RedisSetting {
	var setting model.RedisSetting
	result := repo.db.Where("DEL_FLAG = ? AND ID = ? ", constant.UNDELETE, id).Take(&setting)
	if result.Error != nil {
		// TODO 打印日志
		return nil
	}
	return &setting
}

func (repo *redisSettingRepo) List(setting *model.RedisSetting) []model.RedisSetting {

	if setting != nil && setting.Name != "" {
		repo.db = repo.db.Where("NAME LIKE ?", "%"+setting.Name+"%")
	}

	var records []model.RedisSetting
	result := repo.db.Where("DEL_FLAG = 0 ").Order("CREATE_TIME DESC").Find(&records)
	if result.Error != nil {
		// TODO 打印日志
	}
	for i := range records {
		records[i].Password = "******"
	}
	return records
}

func (repo *redisSettingRepo) Option() []map[string]interface{} {

	var records []map[string]interface{}
	result := repo.db.Model(&model.RedisSetting{}).Select("NAME AS LABEL,ID AS VALUE").Where("DEL_FLAG = 0 ORDER BY CREATE_TIME DESC").Find(&records)
	if result.Error != nil {
		// TODO 打印日志
	}
	return records
}

func (repo *redisSettingRepo) CheckConn(id int) error {
	var setting model.RedisSetting
	result := repo.db.Where("DEL_FLAG = ? AND ID = ? ", constant.UNDELETE, id).Take(&setting)
	if result.Error != nil {
		// TODO 打印日志
		return fmt.Errorf("查询错误,原因:%+w", result.Error)
	}
	client := initRedisClient(&setting)
	err := client.Ping(context.Background()).Err()
	if err != nil {
		return fmt.Errorf("Redis连接失败,原因: %+w", result.Error)
	}
	return nil
}

func NewRedisSettingRepo(db *gorm.DB) *redisSettingRepo {
	return &redisSettingRepo{db}
}
